package vt.ece4564.phonetracker;


import java.util.Calendar;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.telephony.SmsManager;
import android.text.format.Time;
import android.util.Log;

public class GPSMonitor extends HandlerThread{
	private PhoneFinderService m_context;
	private String m_rules;
	private String alertPhoneNumber;
	
	public GPSMonitor(String name, PhoneFinderService context, String rules, String alertPhone) {
		super(name);
		// TODO Auto-generated constructor stub
		m_context = context;
		m_rules = rules;
		alertPhoneNumber = alertPhone;
		listener = new myLocationListener();
    	m_locationManager = (LocationManager)m_context.getSystemService(Context.LOCATION_SERVICE);
		m_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 20000, 10, listener);
	}
	public boolean run_State;
	public boolean isFinished;
	public Handler Handler;
	
	
	private String lat;
	private String lon;
	
	private myLocationListener listener;
	private LocationManager m_locationManager;

	@Override
	public void run() 
	{
		run_State = true;
		isFinished = false;
		
		while (run_State)
		{
			Looper.prepare();
			Log.d("TextMessageMonitor", "Looping...");
			Handler = new Handler()
			{
				public void handleMessage(Message msg)
				{
					Log.d("TextMessageMonitor", "Got a Message");
					
					String message = (String)msg.obj;
					if (!message.equals("TERMINATE"))
					{
						String messageText = "https://maps.google.com/maps?q=";
				    	
				    	
				    	messageText += lat;
				    	messageText += ",";
				    	messageText += lon;
				    	messageText += "+(Your+Phone+is+Here)";
				    	
				    	SmsManager sms = SmsManager.getDefault();
						sms.sendTextMessage((String)msg.obj, null, messageText, null, null);
						
						listener.alertsent = false;
					}
				}
			};
			Looper.loop();
		}
		isFinished = true;
	}
	
	
	
	public class myLocationListener implements LocationListener{
		public boolean alertsent;
    	public myLocationListener()
    	{
    		alertsent = false;
    	}
    	@Override
    	public void onLocationChanged(Location location) {
    		// TODO Auto-generated method stub
    		Log.d("TextMessageMonitor", "Location Update");
			lat = String.valueOf(location.getLatitude());
			lon = String.valueOf(location.getLongitude());
			
			if (!m_rules.equals("dne"))
			{
				Calendar c = Calendar.getInstance();
    			c.setFirstDayOfWeek(Calendar.SUNDAY);
    			c.getTime();
    			String rules[] = m_rules.split("&");
    			for (String curRule: rules)
    			{
    				String details[] = curRule.split("%");
    				int dayofweek = c.get(Calendar.DAY_OF_WEEK);
    				if (dayofweek == convertDayOfWeek(details[6]))
    				{
    					String timePieces[] = details[4].split(":");
    					
    					String timePieces2[] = details[5].split(":");
    					
    					if (c.get(Calendar.HOUR_OF_DAY) >= Integer.parseInt(timePieces[1]) && c.get(Calendar.HOUR_OF_DAY) <= Integer.parseInt(timePieces2[1]))
    					{
    						if (c.get(Calendar.HOUR_OF_DAY) == Integer.parseInt(timePieces[1]))
    						{
    							if (c.get(Calendar.MINUTE) >= Integer.parseInt(timePieces[0]))
    							{
    								confirmLocation(details[2], details[3], details[1]);
    							}
    						}
    						else if (c.get(Calendar.HOUR_OF_DAY) == Integer.parseInt(timePieces2[1]))
    						{
    							if (c.get(Calendar.MINUTE) <= Integer.parseInt(timePieces2[0]))
    							{
    								confirmLocation(details[2], details[3], details[1]);
    							}
    						}
    						else
    						{
    							confirmLocation(details[2], details[3], details[1]);
    						}
    					}
    				}
    			}
			}
    	}

    	@Override
    	public void onProviderDisabled(String provider) {
    		// TODO Auto-generated method stub
    		Log.d("TextMessageMonitor", "Provider Disabled");
    	}

    	@Override
    	public void onProviderEnabled(String provider) {
    		// TODO Auto-generated method stub
    		Log.d("TextMessageMonitor", "Provider Enabled");
    	}

    	@Override
    	public void onStatusChanged(String provider, int status, Bundle extras) {
    		// TODO Auto-generated method stub
    		Log.d("TextMessageMonitor", "Status Changed");
    	}
    	public void confirmLocation(String lati, String longi, String radius)
    	{
    	    
    	    if (Math.abs(distFrom(Float.parseFloat(lati), Float.parseFloat(longi), Float.parseFloat(lat), Float.parseFloat(lon))) > Double.parseDouble(radius))
    	    {
    	    	Log.d("TextMessageMonitor", "Out of Bounds");
    	    	if (!alertsent)
    	    	{
    	    		Log.d("TextMessageMonitor", "Sending an alert");
        	    	String messageText = "Your child is out of bounds! https://maps.google.com/maps?q=";
    		    	
    		    	
    		    	messageText += lat;
    		    	messageText += ",";
    		    	messageText += lon;
    		    	messageText += "+(Your+Child+is+Here)";
    		    	
    		    	if (!alertPhoneNumber.equals("dne"))
    		    	{
    		    		SmsManager sms = SmsManager.getDefault();
    					sms.sendTextMessage(alertPhoneNumber, null, messageText, null, null);
    		    	}
    	    	}
    	    }
    	}
    	public float distFrom(float lat1, float lng1, float lat2, float lng2) 
    	{
    	    double earthRadius = 3958.75;
    	    double dLat = Math.toRadians(lat2-lat1);
    	    double dLng = Math.toRadians(lng2-lng1);
    	    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    	               Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
    	               Math.sin(dLng/2) * Math.sin(dLng/2);
    	    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    	    double dist = earthRadius * c;

    	    int meterConversion = 1609;

    	    return new Float(dist * meterConversion).floatValue();
    	}
    	
    	public int convertDayOfWeek(String day)
    	{
    		if (day.equals("Sun"))
    		{
    			return 1;
    		}
    		else if (day.equals("Mon"))
    		{
    			return 2;
    		}
    		else if (day.equals("Tue"))
    		{
    			return 3;
    		}
    		else if (day.equals("Wed"))
    		{
    			return 4;
    		}
    		else if (day.equals("Thu"))
    		{
    			return 5;
    		}
    		else if (day.equals("Fri"))
    		{
    			return 6;
    		}
    		else if (day.equals("Sat"))
    		{
    			return 7;
    		}
    		return 0;
    	}

    }
}
